package Z4;

/*
 * Zadanie 1 (max 2 punkty)
 Przebadaj klasę przekazaną jako pierwszy argument programu (w pelni kwalifikowana nazwa, 
 czyli paczka.podpaczka.NazwaKlasy) wypisując jej wszystkie :
 – konstruktory
 – pola
 – metody
 Przy kazdej z powyzszych danych wypisz modyfikator dostepu 
 (public, protected czy moze private). 
 Dla konstruktorow i metod wypisz jaki typ danych zwracaja, 
 ile i jakiego typu argumenty pobieraja.

 Uwaga, w tym zadaniu badamy wszystko recznie i tworzymy ladny, przejrzysty raport. 
 Niedopuszczalne jest robienie np. Field field = …; System.out.println( field );
 */

import java.lang.reflect.*;

public class Zadanie1 {
	public static void main(String[] args) {
		String className = "Generics_Reflect.CoffeeGenerator";
		Class c, partypes[];
		Field[] field;
		Constructor[] constucts;
		Method[] m;
		int mod;
		try {
			c = Class.forName(className);
			field = c.getDeclaredFields();
			constucts = c.getDeclaredConstructors();
			m = c.getDeclaredMethods();
			System.out.println("Klasa " + className);

			System.out.println("\npola:");
			for (Field f : field) {
				System.out.println("");
				mod = f.getModifiers();
				System.out.println(f);
				System.out.println("Modyfikator dostępu: " + getModifier(mod));
			}

			System.out.println("\nkonstruktory:");
			for (Constructor ctr : constucts) {
				System.out.println("");
				mod = ctr.getModifiers();
				partypes = ctr.getParameterTypes();
				System.out.print(ctr + "\nModyfikator dostępu: "
						+ getModifier(mod) + "\nZwraca typ: "
						+ ctr.getDeclaringClass() + "\nPobiera "
						+ partypes.length + " argumentów");
				if (partypes.length != 0) {
					System.out.print(" typu: ");
					for (Class tmp : partypes)
						System.out.print(tmp + " ");
					System.out.println("");
				} else
					System.out.println(".");
			}

			System.out.println("\nmetody:");
			for (Method met : m) {
				System.out.println("");
				mod = met.getModifiers();
				partypes = met.getParameterTypes();
				System.out.print(met + "\nModyfikator dostępu: "
						+ getModifier(mod) + "\nZwraca typ: "
						+ met.getReturnType() + "\nPobiera " + partypes.length
						+ " argumentów");
				if (partypes.length != 0) {
					System.out.print(" typu: ");
					for (Class tmp : partypes)
						System.out.print(tmp + " ");
					System.out.println("");
				} else
					System.out.println(".");
			}
		} catch (ClassNotFoundException e) {
			System.err.println("Nie znaleziono klasy");
			e.printStackTrace();

		}
	}

	/*static String getModifier2(int i) {
		String result = "";
		if (Modifier.isAbstract(i))
			result += "abstract ";
		if (Modifier.isFinal(i))
			result += "final ";
		if (Modifier.isInterface(i))
			result += "interface ";
		if (Modifier.isNative(i))
			result += "native ";
		if (Modifier.isPrivate(i))
			result += "private ";
		if (Modifier.isProtected(i))
			result += "protected ";
		if (Modifier.isPublic(i))
			result += "public ";
		if (Modifier.isStatic(i))
			result += "static ";
		if (Modifier.isStrict(i))
			result += "strict ";
		if (Modifier.isSynchronized(i))
			result += "synchronized ";
		if (Modifier.isTransient(i))
			result += "transient ";
		if (Modifier.isVolatile(i))
			result += "volatile ";
		return result.substring(0, result.length() - 1);
	}*/

	static String getModifier(int i) {
		final int PUBLIC = 1, PRIVATE = 2, PROTECTED = 4, 
				STATIC = 8, FINAL = 16, SYNCHRONIZED = 32, 
				VOLATILE = 64, TRANSIENT = 128, NATIVE = 256, 
				INTERFACE = 512, ABSTRACT = 1024, STRICT = 2048; 
			
		String result = "";
		if ((i & ABSTRACT) != 0)
			result += "abstract ";
		if ((i & FINAL) != 0)
			result += "final ";
		if ((i & INTERFACE) != 0)
			result += "interface ";
		if ((i & NATIVE) != 0)
			result += "native ";
		if ((i & PRIVATE) != 0)
			result += "private ";
		if ((i & PROTECTED) != 0)
			result += "protected ";
		if ((i & PUBLIC) != 0)
			result += "public ";
		if ((i & STATIC) != 0)
			result += "static ";
		if ((i & STRICT) != 0)
			result += "strict ";
		if ((i & SYNCHRONIZED) != 0)
			result += "synchronized ";
		if ((i & TRANSIENT) != 0)
			result += "transient ";
		if ((i & VOLATILE) != 0)
			result += "volatile ";
		return result.substring(0, result.length() - 1);
	}
}
